package mushystuff.dtb.core.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.tapestry5.beaneditor.Validate;

@Entity
public class UserStory extends PersistableBean implements Comparable<UserStory> {

	public enum Priority {
		LOW(10), MEDIUM(20), HIGH(30), CRITICAL(50);

		private int level;

		Priority(int level) {
			this.level = level;
		}

		public int level() {
			return level;
		}
	}

	@Validate("required")
	private String story;

	@Validate("required")
	private int storyPoints;

	@Validate("required")
	private Priority priority;

	private Sprint assignedSprint;

	private Product product;

	public UserStory() {
		super();
		priority = Priority.MEDIUM;
		storyPoints = 1;
		story = StringUtils.EMPTY;
	}

	@Column(length = 255, nullable = false)
	public String getStory() {
		return story;
	}

	public void setStory(final String story) {
		this.story = story;
	}

	@Column(nullable = false)
	public int getStoryPoints() {
		return storyPoints;
	}

	public void setStoryPoints(int storyPoints) {
		this.storyPoints = storyPoints;
	}

	@Column(nullable = false)
	public Priority getPriority() {
		return priority;
	}

	public void setPriority(final Priority priority) {
		this.priority = priority;
	}

	@ManyToOne
	public Sprint getAssignedSprint() {
		return assignedSprint;
	}

	public void setAssignedSprint(Sprint assignedSprint) {
		this.assignedSprint = assignedSprint;
	}

	@ManyToOne(optional = false)
	public Product getProduct() {
		return product;
	}

	public void setProduct(Product product) {
		this.product = product;
	}

	@Override
	public int compareTo(final UserStory o) {
	    int res;
		if (this.getPriority() == o.getPriority()) {
			res = getStory().compareTo(o.getStory());
		} else {
			res = o.getPriority().level() - getPriority().level();
		}
		return res;
	}

	@Override
	public boolean equals(final Object obj) {
		if (obj == null) {
			return false;
		}
		if (obj == this) {
			return true;
		}
		if (obj.getClass() != getClass()) {
			return false;
		}
		UserStory rhs = (UserStory) obj;
		return new EqualsBuilder().append(story, rhs.story).append(product,
				rhs.product).isEquals();
	}

	@Override
	public int hashCode() {
		return new HashCodeBuilder(41, 3).append(story).append(product)
				.toHashCode();

	}

	@Override
	public String toString() {
		return new ToStringBuilder(this).append("story", story).append(
				"priority", priority).append("storyPoints", storyPoints)
				.append("assignedSprint", assignedSprint).append("product",
						product).toString();
	}

}
